package com.jzlin.funhub.admin.service.system;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.text.StrSplitter;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzlin.funhub.admin.mapper.SysMessageMapper;
import com.jzlin.funhub.admin.mapper.SysMessageSessionMapper;
import com.jzlin.funhub.admin.model.dto.SysMessageSessionDTO;
import com.jzlin.funhub.admin.model.dto.SysMessageSessionNotReadDTO;
import com.jzlin.funhub.admin.model.entity.SysMessage;
import com.jzlin.funhub.admin.model.entity.SysMessageSession;
import com.jzlin.funhub.admin.model.entity.SysUser;
import com.jzlin.funhub.admin.model.req.SysMessagePostReq;
import com.jzlin.funhub.admin.model.resp.SysMessageResp;
import com.jzlin.funhub.admin.model.resp.SysMessageSessionChatResp;
import com.jzlin.funhub.admin.model.resp.SysMessageSessionResp;
import com.jzlin.funhub.framework.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 站内私信会话表 服务实现类
 * </p>
 *
 * @author jzlin
 * @since 2025-08-26
 */
@Service
public class SysMessageSessionService extends ServiceImpl<SysMessageSessionMapper, SysMessageSession> {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysMessageService sysMessageService;
    /**
     * 查询用户的私信会话列表
     * @param userId 用户id
     * @return
     */
    public List<SysMessageSessionResp> querySessionByUser(Long userId) {
        Long loginUserId = StpUtil.getLoginIdAsLong();

        List<SysMessageSessionDTO> sessionDTOList = baseMapper.querySessionByUser(userId);
        //未读消息数量
        Map<Long, Integer> session2NotReadCountMap = sysMessageService.countSessionNotRead(loginUserId).stream()
                .collect(Collectors.toMap(SysMessageSessionNotReadDTO::getSessionId, SysMessageSessionNotReadDTO::getMessageCount));
        return sessionDTOList.stream().map(dto->{
            SysMessageSessionResp sessionResp = new SysMessageSessionResp();
            Long sessionUserId;
            String sessionUserName, sessionUserAvatar;
            if (loginUserId.equals(dto.getToUserId())) {
                sessionUserId = dto.getFromUserId();
                sessionUserName = dto.getFromUserName();
                sessionUserAvatar = dto.getFromUserAvatar();
            } else {
                sessionUserId = dto.getToUserId();
                sessionUserName = dto.getToUserName();
                sessionUserAvatar = dto.getToUserAvatar();
            }
            sessionResp.setSessionId(dto.getSessionId());
            sessionResp.setUserId(sessionUserId);
            sessionResp.setUserName(sessionUserName);
            sessionResp.setUserAvatar(sessionUserAvatar);
            sessionResp.setMessageContent(dto.getMessageContent());
            sessionResp.setMessageTime(dto.getMessageTime());
            sessionResp.setNotReadCount(session2NotReadCountMap.getOrDefault(dto.getSessionId(), 0));

            return sessionResp;
        }).collect(Collectors.toList());
    }

    /**
     * 查询私信对话
     * @return
     */
    @Transactional
    public SysMessageSessionChatResp querySessionChatByToUser(Long toUserId) {
        Long loginUserId = StpUtil.getLoginIdAsLong();
        Long sessionId =  this.baseMapper.querySessionIdByBothUser(loginUserId, toUserId);
        if (sessionId == null) {
            SysMessageSession session = new SysMessageSession();
            session.setFormUserId(loginUserId);
            session.setToUserId(toUserId);
            this.save(session);
            sessionId = session.getId();
        }
        return querySessionChat(sessionId);
    }

    /**
     * 查询私信对话
     * @return
     */
    public SysMessageSessionChatResp querySessionChat(Long sessionId) {
        Long loginUserId = StpUtil.getLoginIdAsLong();
        SysMessageSession session = this.getById(sessionId);

        SysMessageSessionChatResp resp = new SysMessageSessionChatResp();
        resp.setSessionId(sessionId);
        // 对话用户信息
        Long sessionUserId;
        SysMessageSessionChatResp.SysMessageSessionUser toUser = new SysMessageSessionChatResp.SysMessageSessionUser();
        if (loginUserId.equals(session.getToUserId())) {
            sessionUserId = session.getFormUserId();
        } else {
            sessionUserId = session.getToUserId();
        }
        SysUser toUserInfo = sysUserService.getById(sessionUserId);
        toUser.setUserId(sessionUserId);
        toUser.setUserName(toUserInfo.getNickname());
        toUser.setUserAvatar(toUserInfo.getAvatar());
        resp.setToUser(toUser);

        // 填充对话信息列表
        List<SysMessage> messageList = sysMessageService.listBySessionId(sessionId);
        resp.setMessageList(messageList.stream()
                .map(m -> new SysMessageResp(m.getContent(), m.getCreateTime(), m.getFormUserId().equals(loginUserId)))
                .collect(Collectors.toList()));
        //消息设置为已读
        sysMessageService.readMessageBySessionAndUser(sessionId, loginUserId);
        return resp;
    }


    /**
     * 发送私信
     * @param req
     */
    @Transactional
    public void postMessage(SysMessagePostReq req) {
        SysMessageSession session = this.getById(req.getSessionId());

        Long fromUserId = StpUtil.getLoginIdAsLong();
        Long toUserId = session.getFormUserId().equals(fromUserId) ? session.getToUserId() : session.getFormUserId();

        //保存消息
        SysMessage message = new SysMessage();
        message.setSessionId(req.getSessionId());
        message.setContent(req.getContent());
        message.setFormUserId(fromUserId);
        message.setToUserId(toUserId);
        sysMessageService.save(message);

        //更新会话
        session.setLastMessageId(message.getId());
        session.setLastMessageContent(StringUtils.subSuffix(req.getContent(), 50, "..."));
        session.setLastMessageTime(message.getCreateTime());
        updateById(session);
    }
}
